package com.zhang.security;

import com.zhang.entity.SysUser;
import com.zhang.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

//在配置类中注入后每次登陆的时候都会执行此服务，将登录的用户从数据库中添加到springsecurity中，security内部会进行用户认证，
//认证成功跳转登陆成功处理器，否则跳转认证失败处理器
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    SysUserService sysUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = sysUserService.getByUsername(username);

        if(user == null){
            throw new UsernameNotFoundException("用户名或密码不正确");
        }

        return new AccountUser(user.getId(),user.getUsername(),user.getPassword(),getUserAuthority(user.getId()));
    }

    //获取用户权限信息（角色、菜单权限）
    //在登陆认证或jwt认证中将权限信息保存到springsecurity中后，在controller中的@XXMapping前加上注解@PreAuthorize即可进行权限认证
    //例：@PreAuthorize("hasRole('admin')")//拥有角色admin才可访问， @PreAuthorize("hasAuthority('sys:user:list')")//拥有权限sys::user::list才可访问
    public List<GrantedAuthority> getUserAuthority(Long userId){

        //获取用户权限，不同角色和权限用逗号隔开
        String authority = sysUserService.getAuthorityInfo(userId);

        return AuthorityUtils.commaSeparatedStringToAuthorityList(authority);   //用此工具将字符串转成security需要的格式
    }
}
